﻿#ifndef METAINFO_H
#define METAINFO_H

#include <iostream>
#include <memory>
#include <vector>
#include <signalslot.h>
#include "variant.h"
#include "metatype.h"

class MetaInfo;
class MetaConstructor;
class MetaFunction;
class MetaProperty;
class MetaSignal;
class Reflectable;


template <typename T>
class __INTERFACE_DECLARE{
public:
    static const std::string Name;
    static const bool isValid;
};
template <typename T>
const std::string __INTERFACE_DECLARE<T>::Name = "";

template <typename T>
const bool __INTERFACE_DECLARE<T>::isValid = false;

#define DECL_INTERFACE(name) \
template<>\
const std::string __INTERFACE_DECLARE<name>::Name = #name;\
template <>\
const bool __INTERFACE_DECLARE<name>::isValid = true;\

struct MetaConstructorInfo
{
	std::vector<MetaTypeId> ArgTypes;
	std::vector<std::string> Infos;
};

struct MetaFunctionInfo
{
	std::string Name;
	std::vector<MetaTypeId> ArgTypes;
	MetaTypeId ReturnType;
	std::vector<std::string> Infos;
	enum Flag
	{
		None = 0,
		Static//静态函数
	};

	Flag flags;
};

struct MetaSignalInfo
{
	std::string Name;
	std::vector<MetaTypeId> ArgTypes;
	std::vector<std::string> Infos;
};

struct MetaPropertyInfo {
	std::string Name;
	MetaTypeId Type;
	bool Readable;
	bool Writable;
	std::string NotifierName;
	std::vector<std::string> Infos;
	enum Flag
	{
		None = 0,
		Static//静态属性
	};

	Flag flags;
};

class IMetaInfoBackend :public std::enable_shared_from_this<IMetaInfoBackend>{
public:
	enum ClassFlag
	{
		None = 0 << 0,
	};

	struct CacheData {
		int DefaultConstructor = -1;

		int FunBegin = 0;
		int PropBegin = 0;
		int SignalBegin = 0;
	};

public:
	IMetaInfoBackend(IMetaInfoBackend* SuperClass);
	virtual ~IMetaInfoBackend() {}

	CacheData GetCacheData() const;
	void CalculateCacheData();

	static IMetaInfoBackend* ToLocalFunction(int index, IMetaInfoBackend* meta, int &localIndex);
	static IMetaInfoBackend* ToLocalProperty(int index, IMetaInfoBackend* meta, int &localIndex);
	static IMetaInfoBackend* ToLocalSignal(int index, IMetaInfoBackend* meta, int &localIndex);

	virtual IMetaInfoBackend* SuperClass() const;
	virtual ClassFlag GetClassFlag() const = 0;
	virtual int GetSize() const = 0 ;
	virtual std::string GetClassName() const = 0;
	virtual std::vector<std::string> GetClassInfos() const = 0;

	virtual int NumberOfConstructor() const = 0;
	virtual MetaConstructorInfo GetConstructorInfo(int index) const = 0;
	virtual void Create(void* buffer,int index, const void** args) const = 0;
	virtual void Destory(void* target) const = 0;

	virtual int NumberOfFunctions() const = 0;
	virtual MetaFunctionInfo GetFunctionInfo(int index) const = 0;
	virtual void InvokeMetaFunction(void* target,int index,void* Ret,const void** args) const = 0;

	virtual int NumberOfSignals() const = 0;
	virtual MetaSignalInfo GetSignalInfo(int index) const = 0;
	virtual GenericSignal* GetSignal(void* target,int index) const = 0;

	virtual int NumberOfPropertys() const = 0;
	virtual MetaPropertyInfo GetPropertyInfo(int index) const = 0;
	virtual void ReadProperty(void* target,int index,void* buffer) const = 0;
	virtual void WriteProperty(void* target,int index, const void* src) const = 0;

	virtual bool isCastable() const = 0;
	virtual Reflectable* MetaCast(void* target) const = 0;
private:
	std::shared_ptr<IMetaInfoBackend> m_SuperClass;
	CacheData cacheData;
};

class REFLECTX_EXPORT MetaInfo
{
private:

public:
	MetaInfo(IMetaInfoBackend* data);
    MetaInfo();
public:
	IMetaInfoBackend* GetBackend() const;

    bool IsValid() const;

    std::string ClassName() const;

	bool IsBaseOf(const MetaInfo& other) const;


    void* Create(void *buffer = NULL) const;

    void Destory(void* target) const;//对目标地址上的对象执行析构函数但不销毁内存
    void Delete(void* target) const;//对目标地址上的对象执行析构函数并销毁内存

    bool IsDefaultCreatable() const;

	bool IsCastable() const;//该类型是否能进行动态类型转换，需要该类继承Reflectable,当为true时，metacast可用

    int Size() const;

    bool operator == (const MetaInfo& info) const;

	
	MetaConstructor GetConstructor(int index) const;
	int ConstructorCount() const;
	int IndexOfConstructor(const char* signature) const;
	int IndexOfConstructor(const std::vector<MetaTypeId> &argTypes) const;

    MetaFunction GetFunction(int index) const;
    int FunctionCount() const;
    int IndexOfFunction(const char* signature) const;
	int IndexOfFunction(const char* functionName,const std::vector<MetaTypeId> &argTypes) const;
    int FunctionBeginIndex() const;


    MetaProperty GetProperty(int index) const;
    int PropertyCount() const;
    int IndexOfProperty(const char* propertyName) const;
    int PropertyBeginIndex() const;

    MetaSignal GetSignal(int index) const;
    int SignalCount() const;
	int IndexOfSignal(const char* signature) const;
	int IndexOfSinal(const char* name,const std::vector<MetaTypeId>& argTypes) const;
    int SignalBeginIndex() const;

	std::vector<std::string> GetClassInfo() const;

    template<typename T>
    std::string GetInterfaceId() const{
        return __INTERFACE_DECLARE<T>::Name;
    }

	bool CanMetaCast() const;

    template<typename I>
    I* MetaCast(void* target) const{
		return dynamic_cast<I*>(MetaCast(target));
    }

    //元转换，当一个类继承了Reflectable时，它就可以通过这里转换为Reflectable
	Reflectable* MetaCast(void* target) const;

private:

private:
	std::shared_ptr<IMetaInfoBackend> _d;
};

#endif // METAINFO_H
